'''
@author: Aurelien Deharbe


This file is part of Cute-Server.

Cute-Server is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Cute-Server is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Cute-Server.  If not, see <http://www.gnu.org/licenses/>.
'''

from PySide.QtCore import * #@UnusedWildImport
from PySide.QtGui import * #@UnusedWildImport

class CCommandError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

def capture(cmd):
    spl = cmd.split("->")
    if len(spl) == 1:
        return (cmd, None)
    if len(spl) > 2:
        raise CCommandError("capture")
    return [i.strip() for i in spl]

def getVars(cmd):
    lvl = 0
    capt = ""
    vars = []
    for i in range(len(cmd)):
        if lvl == 0 and cmd[i] == '<':
            lvl = 1
            continue
        if cmd[i] == '<':
            lvl = lvl + 1
        elif cmd[i] == '>':
            lvl = lvl - 1
            if lvl == 0:
                vars.append(capt)
                capt = ""
                continue
        if lvl > 0:
            capt = capt + cmd[i]
    return vars

def getSolvedVars(vars, symbols):
    return [_solveVar(i, symbols) for i in vars]

def _solveVar(var, symbols):
    vl = var.split(".")
    if len(vl) == 1:
        if var not in symbols.keys():
            raise CCommandError("var")
        return "sym[\"" + var + "\"]"
    s = None
    for elt in vl:
        if elt[0] == '*':
            if elt == "*":
                typ = eval("QWidget")
            else:
                try:
                    typ = eval(elt[1:])
                except:
                    raise CCommandError("var")
            if not s:
                raise CCommandError("var")
            children = s.findChildren(typ)
            ret = []
            for key,sym in symbols.items():
                if sym in children:
                    ret.append("sym[\"" + key + "\"]")
            if not ret:
                raise CCommandError("var")
            return ret
        
        if elt[0] == '?':
            if elt == "?":
                typ = eval("QWidget")
            else:
                try:
                    typ = eval(elt[1:])
                except:
                    raise CCommandError("var")
            if not s:
                raise CCommandError("var")
            child = s.findChild(typ)
            ret = None
            for key,sym in symbols.items():
                if sym == child:
                    ret = "sym[\"" + key + "\"]"
            if not ret:
                raise CCommandError("var")
        
        vs = getVars(elt)
        if len(vs) != 1:
            raise CCommandError("var")
        vs = vs[0]
        if vs not in symbols.keys():
            raise CCommandError("var")
        if not s:
            s = symbols[vs]
        else:
            children = s.findChildren(QObject)
            s = symbols[vs]
            if s not in children:
                raise CCommandError("var")
        ret = "sym[\"" + vs + "\"]"
    return ret

def getAllCommands(cmd, vars, solvedVars):
    l = filter(lambda x: type(x) == list, solvedVars)
    if len(l) > 1:
        raise CCommandError("vars")
    if not l:
        acmd = cmd
        for i in range(len(vars)):
            acmd = acmd.replace("<" + vars[i] + ">",
                                solvedVars[i], 1)
        return [acmd]
    else:
        l = l[0]
        ret = []
        for n in range(len(l)):
            acmd = cmd
            for i in range(len(vars)):
                if type(solvedVars[i]) == list:
                    acmd = acmd.replace("<" + vars[i] + ">",
                                        solvedVars[i][n], 1)
                else:
                    acmd = acmd.replace("<" + vars[i] + ">",
                                        solvedVars[i], 1)
            ret.append(acmd)
    return ret

def isPrimitiveType(obj):
    t = type(obj)
        
    if t == int:
        return True
    if t == long:
        return True
    if t == str:
        return True
    if t == unicode:
	return True
    if t == float:
        return True
    if t == bool:
        return True
    if t == list:
        for elt in obj:
            if not isPrimitiveType(elt):
                return False
        return True
    if t == dict:
        for (key, elt) in obj.values():
            if not isPrimitiveType(key):
                return False
            if not isPrimitiveType(elt):
                return False
        return True
    return False



if __name__ == '__main__':
    print "Please use the cuteserver script to run it"
